package com.ys.service.storage.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ys.config.MenuId;
import com.ys.dto.AddDto;
import com.ys.entity.base.CheckByGrid;
import com.ys.entity.purchase.TcgOfflinePurchaseInStorage;
import com.ys.entity.storage.*;
import com.ys.entity.sys.YsGridCol;
import com.ys.enume.base.TransactionTypeEnum;
import com.ys.enume.storage.TccOnlineAssembleErrorEnum;
import com.ys.enume.storage.TccOnlinePutonEnum;
import com.ys.enume.storage.TccStockSourceEnum;
import com.ys.mapper.storage.*;
import com.ys.service.business.TcwAccountDetailedForCompanyService;
import com.ys.service.storage.TccOfflineAssembleService;
import com.ys.service.storage.TccOnlinePutonService;
import com.ys.service.storage.TccStockControlService;
import com.ys.service.sys.CommonApiService;
import com.ys.util.CheckUtil;
import com.ys.vo.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

//线上质检上架
@Service("tccOnlinePutonService")
public class TccOnlinePutonServiceImpl implements TccOnlinePutonService {

	@Autowired
	private TccOnlinePutonMapper tccOnlinePutonMapper;

	@Autowired
	private TccOnlinePutonLocationMapper tccOnlinePutonLocationMapper;

	@Autowired
	private CommonApiService<TccOnlinePuton> commonApiService;

	@Autowired
	private CheckUtil checkUtil;

	@Autowired
	private StorageMapper storageMapper;

	@Autowired
	private TccStockControlMapper tccStockControlMapper;

	@Autowired
	private TccStockControlService tccStockControlService;

	@Autowired
	private TccOfflineAssembleService tccOfflineAssembleService;


	private final Long GRID = 68L;

	@Autowired
	private TcwAccountDetailedForCompanyService tcwAccountDetailedForCompanyService;


	@Override
	@Transactional
	public R add(String assembleBid,String spBm,Integer putonNum, Long stockControlId) throws Exception {
		/*
		TccAssemble tccAssemble = new TccAssemble().setBid(bidAssemble).queryFirst();
		if (tccAssemble.getState() != TccAssembleEnum.State.YES.value) {
			return R.error("组装单尚未完成，无法添加");
		}
		 */
		String bid = commonApiService.getCommonNextBid(MenuId.TCC_OnlinePuton);
		Integer putonStatus = TccOnlinePutonEnum.PutonStatus.NOT.value;
		TccOnlinePuton entity = TccOnlinePuton.tccOnlinePuton(bid, assembleBid, spBm,stockControlId, new BigDecimal(putonNum),putonStatus, null,1);
		tccOnlinePutonMapper.insert(entity);

		return R.ok("操作成功");
	}



	//质检上架、并审核
	@Override
	@Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
	public R doQualityTesting(Map<String, Object> params) throws Exception {

		if(checkUtil.isNullByObject(params.get("id"))){
			return R.error("id信息为空");
		}
		if(checkUtil.isNullByObject(params.get("chw"))){
			return R.error("货位信息为空");
		}
		TccOnlinePuton entity =new TccOnlinePuton().setId(Long.parseLong(params.get("id").toString())).setStatus(1).queryFirst();
		if(entity!=null && entity.getBid()!=null){
			if(entity.getPutonStatus()==1){
				return R.error("已上架，无需再操作");
			}

			//获取库存信息
			TccStockControl tccStockControl = new TccStockControl().setId(entity.getStockControlId()).queryFirst();
			if(tccStockControl==null || tccStockControl.getProductCode()==null){
				return R.error("未查询到库存信息！");
			}

			//1、修改库位信息
			//详情页已进行入库设置的，批量上架设置的库位不覆盖
			if(entity.getChwSaveType()==null || entity.getChwSaveType()==0){
				//删除旧的
				storageMapper.deleteTccOnlinePutonLocationByPutonOnlineId(entity.getId());
				//设置新的
				TccOnlinePutonLocation sonEntity = new TccOnlinePutonLocation();
				sonEntity.setPutonOnlineId(entity.getId());
				sonEntity.setStockControlId(entity.getStockControlId());
				sonEntity.setSubPutonNum(entity.getPutonNum());
				sonEntity.setChw(params.get("chw").toString());
				tccOnlinePutonLocationMapper.insert(sonEntity);
			}

			//2、库存修改
			//查询线上质检上架货位信息表
			List<TccOnlinePutonLocation> sonList = new TccOnlinePutonLocation().setPutonOnlineId(entity.getId()).queryList();
			for(TccOnlinePutonLocation sonInfo:sonList){

				if(sonInfo.getStockControlId()!=null){//如果是默认库存信息
					//修改货位信息
					//库存表信息修改
					//库存天数 = 上架审核时间-当天
					//tccStockControl.setSdays(0);//默认0
					//入库时间 = 上架审核时间
					//tccStockControl.setDrksj(entity.getUpdateTime());
					//货位编码
					tccStockControl.setChw(sonInfo.getChw());

					//通过货位编码查询信息，兼容1.0的字段
					Map<String, Object> tccLocationMap = new TccLocation()
							.addLeftJoin("TCC_WarehouseArea CWA ON CWA.Ckq = A.Ckq")//库区
							.addLeftJoin("TCC_Warehouse CW ON CW.Cck = CWA.Cck")//仓库
							.addField("CW.vck,CWA.vkq,A.vhw")
							.setChw(sonInfo.getChw())
							.queryFirstMap();
					String vHw = tccLocationMap.get("vhw").toString();
					String vKq = tccLocationMap.get("vkq").toString();
					String gDepot = tccLocationMap.get("vck").toString();
					tccStockControl.setVhw(vHw);
					tccStockControl.setVkq(vKq);
					tccStockControl.setGdepot(gDepot);
					//tccStockControl.setProductNum(tccStockControl.getProductNumAll());

					tccStockControlMapper.update(tccStockControl);
					//解冻
					tccStockControlService.thaw(sonInfo.getStockControlId(), sonInfo.getSubPutonNum().intValue(), TccStockSourceEnum.Source.TCC_OnlinePuton.value,entity.getBid(), sonInfo.getId());
				}else {
					String remark = "线上质检上架："+entity.getBid();
					//旧库存解冻并出库；解冻流水、出库流水
					//解冻
					tccStockControlService.thaw(entity.getStockControlId(), sonInfo.getSubPutonNum().intValue(), TccStockSourceEnum.Source.TCC_OnlinePuton.value,entity.getBid(), sonInfo.getId());
					//出库
					tccStockControlService.outWithRunning(entity.getStockControlId() ,remark+"（出库）", sonInfo.getSubPutonNum().intValue(),entity.getBid(), TccStockSourceEnum.Source.TCC_OnlinePuton.value,entity.getId());

					//新增新的库存信息
					R res = tccStockControlService.inWithRunning(tccStockControl.getRkBid(),sonInfo.getChw(),tccStockControl.getProductName(),
							sonInfo.getSubPutonNum().intValue(),entity.getSpBm(),sonInfo.getSubPutonNum().intValue(),tccStockControl.getPurchasePrice(),
							tccStockControl.getPurchaseTotalPriceAll(),tccStockControl.getAllotPrice(),tccStockControl.getTotalAllotPrice(),
							tccStockControl.getVgsbm(), new Date(),
							tccStockControl.getIsParent(),entity.getBid(),TccStockSourceEnum.Source.TCC_OnlinePuton.value,remark, tccStockControl.getCompanyVid(),entity.getAssembleBid(),entity.getId());

					//获取新库存id，并回填
					long tccStockControlId = Long.parseLong(res.get("data").toString());
					sonInfo.setStockControlId(tccStockControlId);
					tccOnlinePutonLocationMapper.update(sonInfo);
				}
			}

			TccOfflineAssemble tccOfflineAssemble = new TccOfflineAssemble().setBid(entity.getAssembleBid()).queryFirst();
			// 子件出库
			List<TccOfflineAssembleItem> listTccOfflineAssembleItem = new TccOfflineAssembleItem().setPbid(tccOfflineAssemble.getBid()).queryList();
			if (listTccOfflineAssembleItem.size() == 0){
				return R.error("组装子件数据为空!");
			}
			TcgOfflinePurchaseInStorage tcgOfflinePurchaseInStorage = new TcgOfflinePurchaseInStorage().setId(listTccOfflineAssembleItem.get(0).getOfflinePurchaseStorageId()).queryFirst();

			if (tccOfflineAssemble.getParentAssembleNumber() != 0) {
				BigDecimal fJe = new BigDecimal(tccOfflineAssemble.getParentAssembleNumber()).multiply(BigDecimal.ONE);
				//划出流水,划出至仓储部,备注组装单，商品编码+商品名称+数量
				tcwAccountDetailedForCompanyService.addTcwAccountDetailedForCompanyNoTrigger(
						tcgOfflinePurchaseInStorage.getVgsbm(), "GS0608", TransactionTypeEnum.BusinessType.TCC_Distribute_ZZ.name, fJe.negate(),
						tccOfflineAssemble.getCreateTime(), tccOfflineAssemble.getAuditTime(),
						"线上商品组装单:" + tccOfflineAssemble.getBid() + "，商品编码:" + tcgOfflinePurchaseInStorage.getProductCode() + "，商品名称:" + tcgOfflinePurchaseInStorage.getProductName()
								+ "，数量:" + tccOfflineAssemble.getParentAssembleNumber(),
						 tccOfflineAssemble.getBid(), null);
				//划入流水
				tcwAccountDetailedForCompanyService.addTcwAccountDetailedForCompanyNoTrigger(
						"GS0608", tcgOfflinePurchaseInStorage.getVgsbm(), TransactionTypeEnum.BusinessType.TCC_Distribute_ZZ.name, fJe,
						tccOfflineAssemble.getCreateTime(), tccOfflineAssemble.getAuditTime(),
						"线上商品组装单:" + tccOfflineAssemble.getBid() + "，商品编码:" + tcgOfflinePurchaseInStorage.getProductCode() + "，商品名称:" + tcgOfflinePurchaseInStorage.getProductName()
								+ "，数量:" + tccOfflineAssemble.getParentAssembleNumber(),
						tccOfflineAssemble.getBid(),  null);
			}

			//3、上架
			//上架状态变更为已上架、填入表单“审核时间”
			entity.setPutonStatus(TccOnlinePutonEnum.PutonStatus.YES.value);//上架状态(0.待上架|1已上架)
			if(entity.getChwSaveType()==null)entity.setChwSaveType(0);//货位保存方式
			tccOnlinePutonMapper.update(entity);


			return R.ok();
		}else {
			return R.error("未查询到质检上架单据信息");
		}

	}



	//设置货位
	@Override
	@Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
	public R setChw(Map<String, Object> params) throws Exception {
		TccOnlinePuton entity = JSON.parseObject(JSON.toJSONString(params), TccOnlinePuton.class);
		entity.setChwSaveType(1);

		//保存列表信息
		R saveItemRes = saveItem(params,entity);
		if(saveItemRes.getCode()==1){
			return saveItemRes;
		}
		tccOnlinePutonMapper.update(entity);

		return R.ok(AddDto.closeAndReload());
	}



	//保存子列表信息
	public R saveItem(Map<String, Object> params, TccOnlinePuton entity) throws Exception{
		//保存列表信息
		List<Map<String, Object>> subDataList = new ArrayList<>();
		if(params.get("subData")!=null){
			JSONArray subData = JSON.parseArray(params.get("subData").toString());
			CheckByGrid checkByGrid = checkParamsByGrid(subData,GRID,params);
			if(checkUtil.isNotNullByObject(checkByGrid.getErrMsg())){
				return R.error(checkByGrid.getErrMsg());
			}
			subDataList = checkByGrid.getSubDataList();
		}else {
			return R.error("列表信息为空！");
		}

		//先删除详情数据
		storageMapper.deleteTccOnlinePutonLocationByPutonOnlineId(entity.getId());
		//再新增
		for (int i = 0; i < subDataList.size(); i++) {
			Map<String, Object> item = subDataList.get(i);
			TccOnlinePutonLocation itemInfo = JSON.parseObject(JSON.toJSONString(item), TccOnlinePutonLocation.class);
			itemInfo.setStatus(1);
			itemInfo.setPutonOnlineId(entity.getId());
			//第一条的库存id默认设置成与母表一致，其余设为null
			if(i==0){
				itemInfo.setStockControlId(entity.getStockControlId());
			}
			else {
				itemInfo.setStockControlId(null);
			}
			//新增
			tccOnlinePutonLocationMapper.insert(itemInfo);
		}
		return R.ok();
	}
	




	/**
	 * 子表参数验证
	 */
	public CheckByGrid checkParamsByGrid(JSONArray subDataArray, Long gridId,Map<String, Object> params) throws Exception {
		CheckByGrid checkByGrid = new CheckByGrid();
		//获取pc字段数据
		List<YsGridCol> listField = new YsGridCol()
				.setGridId(gridId)
				.setOrderby("A.SortNo ASC")
				.queryList();
		StringBuffer backMsg = new StringBuffer();
		List<Map<String, Object>> subDataList = new ArrayList<>();

		//获取上架数量
		BigDecimal putonNum = BigDecimal.ZERO;
		if(checkUtil.isNotNullByObject(params.get("putonNum"))){
			putonNum = new BigDecimal(params.get("putonNum").toString());
		}

		BigDecimal subPutonNumTotal = BigDecimal.ZERO;

		if(subDataArray!=null && subDataArray.size()>0){
			for (int i = 0; i < subDataArray.size(); i++) {
				JSONObject jsonObject = subDataArray.getJSONObject(i);
				Map<String, Object> paramsNewByRecord = new HashMap<>();
				for (String key : jsonObject.keySet()) {
					paramsNewByRecord.put(key, jsonObject.get(key));
				}
				subDataList.add(paramsNewByRecord);
			}
			//验证
			for(int i = 0;i<subDataList.size();i++){
				StringBuffer backMsgByRow = new StringBuffer();
				Map<String, Object> subData = subDataList.get(i);
				//验证必填字段的非空；其他字段的长度限制、类型
				backMsgByRow.append(checkUtil.checkTableColLengthAndDataTypeByGrid(
						"TCC_OnlinePutonLocation",
						listField,
						subData,
						ysColItem->
								ysColItem.getCode().equals("subPutonNum")
										|| ysColItem.getCode().equals("chw")
				));
				if(checkUtil.isNotNullByObject(subData.get("subPutonNum"))){
					subPutonNumTotal = subPutonNumTotal.add(new BigDecimal(subData.get("subPutonNum").toString()));
				}
				if(checkUtil.isNotNullByObject(backMsgByRow)){
					backMsg.append("列表第")
							.append((i+1))
							.append("行，")
							.append(backMsgByRow);
				}
			}

			//验证子列表的上架数量总和 是否与母表一致
			if (putonNum.compareTo(BigDecimal.ZERO)==0 || putonNum.compareTo(subPutonNumTotal)!=0){
				backMsg.append("子列表的上架数量总和与母表总数量不一致");
			}

		}else{
			backMsg = new StringBuffer("列表信息为空");
		}
		checkByGrid.setErrMsg(backMsg.toString());
		checkByGrid.setSubDataList(subDataList);

		return checkByGrid;
	}


	//设置查询sql
	@Override
	@Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
	public TccOnlinePuton setSeachSqlByCommon(TccOnlinePuton cond) throws Exception{
		cond
				.addField("CASE WHEN A.PutonStatus=1  THEN '' ELSE FORMAT(A.UpdateTime, 'yyyy-MM-dd HH:mm:ss') END  _ys_updateTime")//上架时间

				.addLeftJoin("TCC_OnlinePutonLocation B ON B.PutonOnlineId = A.Id")//线上质检上架货位信息表
				.addField("CASE WHEN B.SubPutonNum IS NULL  THEN A.PutonNum ELSE B.SubPutonNum END putonNumByReality")//实际上架数量
				.addField("CASE WHEN B.StockControlId IS NULL  THEN A.StockControlId ELSE B.StockControlId END subStockControlId")//库存id

				.addLeftJoin("TCC_Location C ON C.Chw = B.Chw")
				.addLeftJoin("TCC_WarehouseArea CWA ON CWA.Ckq = C.Ckq")//库区
				.addLeftJoin("TCC_Warehouse CW ON CW.Cck = CWA.Cck")//仓库
				.addField("CW.vck,CWA.vkq,C.vhw")

				.addLeftJoin("TP_ProductActive D ON D.Code = A.SpBm")
				.addField("D.Name AS spName")//商品名称
				.addField("D.LinkIn AS linkIn")//采购链接

				.addLeftJoin("TCC_OfflineAssemble E ON E.Bid = A.AssembleBid")//组装单
				.addField("E.AssemblyListBid AS assemblyListBid")//组装清单号

				.addLeftJoin("(SELECT MAX(FI.offlinePurchaseStorageId) AS offlinePurchaseStorageId , FI.Pbid FROM TCC_OfflineAssembleItem FI GROUP BY FI.Pbid) F ON F.Pbid = E.Bid")//组装单子表

				.addLeftJoin("TCG_OfflinePurchaseInStorage G on G.id = F.offlinePurchaseStorageId")
				.addField("G.productImgOne")//商品图片1
				.addField("G.productImgTwo")//商品图片2
				.addField("G.productImgThree")//商品图片3
				//.addField("G.bid offlinePurchaseInStorageBid")//采购入库单号

				.addLeftJoin("THR_OperateCompanyApply H ON H.Vgsbm = G.Vgsbm ")//运营公司管理表
				.addField("H.Vgsjc AS vgsjc")//采购公司简称
				.addField("H.Vgsbm AS vgsbm")//采购公司编码

				.addLeftJoin("TCG_PurchaseByOrderSon I ON I.id = G.PurchaseOrderSonId")//采购订单子表
				.addLeftJoin("TCG_PurchaseByOrder J ON I.Pid = J.id")//采购订单
				.addField("J.Bid purchaseOrderBid")//订单单号
				.addField("J.id purchaseOrderId")//订单id
				.addField("J.PlanBid AS purchasePlanBid")//计划单号

				.addLeftJoin("TS_UserChange K on K.Id = H.OperatorChangeId")
				.addField("K.UserId operatorUserId")//运营人工号
				.addField("K.UserName operatorUserName")//运营人

				.setStatus(1)
		;

		return cond;
	}


	//获取母表信息
	@Override
	public Map<String, Object> getExtraParam(Long id) throws Exception{
		return new TccOnlinePuton()
				.addLeftJoin("TP_ProductActive B ON B.Code = A.SpBm")
				.addField("B.Name AS spName")//商品名称
				.addField("B.LinkIn AS linkIn")//采购链接
				.setId(id)
				.queryFirstMap();
	}

	//获取子列表信息
	public List<Map<String, Object>> getItemListByPid(Long id) throws Exception{
		return new TccOnlinePutonLocation()

				.addLeftJoin("TCC_OnlinePuton B ON A.PutonOnlineId = B.Id")
				.addField("B.PutonNum AS putonNum")//上架数量
				.addField("B.PutonStatus AS putonStatus")//上架状态(0.待上架|1已上架)
				.addField("B.SpBm AS spBm")//商品编码

				.addLeftJoin("TCC_Location C ON C.Chw = A.Chw")
				.addLeftJoin("TCC_WarehouseArea CWA ON CWA.Ckq = C.Ckq")//库区
				.addLeftJoin("TCC_Warehouse CW ON CW.Cck = CWA.Cck")//仓库
				.addField("CW.vck,CWA.vkq,C.vhw")

				//.addLeftJoin("TP_ProductActive D ON D.Code = B.SpBm")
				//.addField("D.Name AS spName")//商品名称
				.setPutonOnlineId(id)
				.queryMap();
	}


	//组装回退
	@Override
	@Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
	public R back(Long id) throws Exception {
		//获取质检上架单信息
		TccOnlinePuton tccOnlinePuton = new TccOnlinePuton().setId(id).queryFirst();
		if(tccOnlinePuton ==null || tccOnlinePuton.getBid()==null){
			return R.error("未查询到质检上架单信息");
		}
		//获取组装单信息
		TccOfflineAssemble tccOfflineAssemble = new TccOfflineAssemble().setBid(tccOnlinePuton.getAssembleBid()).queryFirst();
		if(tccOfflineAssemble ==null || tccOfflineAssemble.getId()==null){
			return R.error("未查询到组装单信息");
		}
		//获取报错单信息
		TccOnlineAssembleError tccOnlineAssembleError = new TccOnlineAssembleError()
				.setAssembleId(tccOfflineAssemble.getId())
				.queryFirst();

		//验证质检上架单状态
		if(tccOnlinePuton.getPutonStatus().equals(TccOnlinePutonEnum.PutonStatus.YES.value)){
			return R.error("该质检上架单已上架，无法回退");
		}

		//验证报错单状态
		if(tccOnlineAssembleError!=null && tccOnlineAssembleError.getBid()!=null){
			if(!(tccOnlineAssembleError.getHandleStatus().equals(TccOnlineAssembleErrorEnum.HandleStatus.DID_NOT_DO.value)
					|| tccOnlineAssembleError.getHandleStatus().equals(TccOnlineAssembleErrorEnum.HandleStatus.NORMAL.value))){
				return R.error("对应的组装报错单【"+tccOnlineAssembleError.getBid()+"】状态是"+TccOnlineAssembleErrorEnum.HandleStatus.getName(tccOnlineAssembleError.getHandleStatus())+"，无法回退");
			}
		}

		//组装回退
		if(tccOnlineAssembleError!=null && tccOnlineAssembleError.getBid()!=null){
			List<TccOnlineAssembleErrorItem> errorItemList = new TccOnlineAssembleErrorItem().setPbid(tccOnlineAssembleError.getBid()).queryList();
			//异常组装回退
			tccOfflineAssembleService.doErrorBack(tccOnlinePuton.getAssembleBid(),errorItemList);
		}else {
			//正常组装回退
			tccOfflineAssembleService.doBack(tccOnlinePuton.getAssembleBid());

		}
		return R.ok();
	}


	//质检上架单删除，根据商品组装单号
	@Override
	public R delByAssembleBid(String assembleBid) throws Exception {
		storageMapper.updateTccOnlinePutonStateByAssembleBid(assembleBid);
		return R.ok();
	}




}
